#include "widget.h"
#include "ui_widget.h"
#include "sqliteutil.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    tran = new QTranslator(this);
    tran->load(":/openlocker_zh_CN.qm");
    QApplication::installTranslator(tran);
    ui->retranslateUi(this);

    // 初始化时发送按键失能
    ui->lock_status_btn->setEnabled(false);
    ui->all_status_btn->setEnabled(false);
    ui->open_one_btn->setEnabled(false);
    ui->open_all_btn->setEnabled(false);
    sqlite_util.createTable(SqliteUtil::TABLE_NAME);
    connect(&sqlite_util, SIGNAL(inserted()), this, SLOT(drawTable_slot()));
    connect(this, SIGNAL(delTable()), this, SLOT(delTable_slot()));
}

Widget::~Widget()
{
    delete ui;
    delete tran;
    sqlite_util.deleteTable(SqliteUtil::TABLE_NAME);
}

int Widget::insertData(QString table_name, int board_pos, int lock_pos, QString status)
{
    QString insert_sql = "insert into " + table_name + " (%1, %2, %3) values (?, ?, ?)";
    QString s = insert_sql.arg("board_pos").arg("lock_pos").arg("status");
    qDebug() << s;
    QList<QVariant> list;

    list.append(board_pos);
    list.append(lock_pos);
    list.append(status);
    int rs = sqlite_util.executeInt(s, list);
    emit sqlite_util.inserted();
    return rs;
}

void Widget::drawTable_slot()
{
    QString query = QString("select board_pos,lock_pos,status from %1").arg(SqliteUtil::TABLE_NAME);
    model = new QSqlQueryModel(ui->tableView);
    sqlite_util.executeQueryModel(model, query);
    //model->setHeaderData(0, Qt::Horizontal, QObject::tr("编号"));
    model->setHeaderData(0, Qt::Horizontal, QObject::tr("板号"));
    model->setHeaderData(1, Qt::Horizontal, QObject::tr("锁号"));
    model->setHeaderData(2, Qt::Horizontal, QObject::tr("状态"));
    ui->tableView->setColumnWidth(0, 134);
    ui->tableView->setColumnWidth(1, 134);
    ui->tableView->setColumnWidth(2, 133);
    ui->tableView->setModel(model);
}

void Widget::delTable_slot()
{
    QString query = QString("delete from %1").arg(SqliteUtil::TABLE_NAME);
    sqlite_util.executeQuery(query);
}

QString Widget::crcSum16(QString data)
{
    QStringList list = data.split(QString(" "));
    qint32 sum = 0;
    for (int i=0; i<list.size(); i++) {
        QString temp = list[i];
        qint32  d = 0;
        if (!temp.isEmpty()) {
            d = temp.toInt(nullptr, 16);
            sum += d;
        }
    }
    if (QString::number(sum, 16).size() > 2) {
        return QString::number(sum, 16).mid(1, 2).toUpper();
    }
    return QString::number(sum, 16).toUpper();
}

void Widget::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
        case QEvent::LanguageChange:
            ui->retranslateUi(this);
            break;
        default:
            break;
    }
}

void Widget::on_combo_currentIndexChanged(int index)
{
    if (index == 0) {
        tran->load(":/openlocker_zh_CN.qm");
    } else {
        tran->load(":/openlocker_en.qm");
    }
    QApplication::installTranslator(tran);
    ui->retranslateUi(this);
}


void Widget::on_check_btn_clicked()
{
    qDebug() << "on clicked";
    ui->com_port->clear();
    qDebug() << serial.getAvailablePortNameList();
    QStringList sl = serial.getAvailablePortNameList();
    for(int i=0; i<sl.size(); i++) {
        ui->com_port->addItem(sl[i]);
    }
}

void Widget::on_open_btn_clicked()
{
    if (ui->open_btn->text() == QString("打开串口")) {
        // 设置串口名称
        QString port = ui->com_port->currentText();
        qDebug() << port;
        if (port.isEmpty()) {
            QMessageBox::about(NULL, QObject::tr("提示"), QObject::tr("请先检测并选择可用的串口"));
            return;
        }
        // 波特率
        qint32 baudRate = ui->com_baudRate->currentText().toInt();

        if (!serial.isOpen()) {
            if (!serial.openPort(port, baudRate, QSerialPort::Data8, QSerialPort::NoParity, QSerialPort::OneStop)) {
                QMessageBox::about(NULL, QObject::tr("提示"), QObject::tr("无法打开串口"));
                return;
            }
        }

        // 禁用下拉菜单
        ui->com_port->setEnabled(false);
        ui->com_baudRate->setEnabled(false);

        // 修改按钮内容
        ui->open_btn->setText(QString("关闭串口"));

        // 启用发送按钮
        //ui->send_btn->setEnabled(true);
        ui->all_status_btn->setEnabled(true);
        ui->lock_status_btn->setEnabled(true);
        ui->open_one_btn->setEnabled(true);
        ui->open_all_btn->setEnabled(true);
    } else {
        // 启用下拉菜单
        ui->com_port->setEnabled(true);
        ui->com_baudRate->setEnabled(true);

        // 改变按钮内容
        ui->open_btn->setText(QString("打开串口"));

        // 禁用发送按钮
        //ui->send_btn->setEnabled(false);
        ui->all_status_btn->setEnabled(false);
        ui->lock_status_btn->setEnabled(false);
        ui->open_one_btn->setEnabled(false);
        ui->open_all_btn->setEnabled(false);
        // 关闭串口
        serial.closePort();
    }
}

/**
 * @brief Widget::on_lock_status_btn_clicked
 * 获取锁状态
 */
void Widget::on_lock_status_btn_clicked()
{
    emit delTable();
    QString board_pos = ui->board_pos->text();
    QString lock_pos = ui->lock_pos->text();
    if (board_pos.isEmpty()) {
        QMessageBox::about(NULL, QObject::tr("提示"), QObject::tr("请输入板号！"));
        return;
    }
    if (lock_pos.isEmpty()) {
        QMessageBox::about(NULL, QObject::tr("提示"), QObject::tr("请输入锁号！"));
        return;
    }

    ui->lock_status_btn->setEnabled(false);
    // 转换输入的板号和锁号为16进制
    QString bp = QString("%1").arg(board_pos.toInt(), 2, 16, QLatin1Char('0'));
    QString lp = QString("%1").arg(lock_pos.toInt(), 2, 16, QLatin1Char('0'));
    // 拼接发送命令
    QString send_cmd = WlLocker::status_one_send.arg(bp).arg(lp);
    // 计算命令的crc值
    QString crc = crcSum16(send_cmd);
    send_cmd = send_cmd + crc;

    ui->send_cmd->setText(send_cmd);
    QByteArray recv = serial.sendAndRead(send_cmd);
    // 计算返回结果
    // QString recv_cmd = WlLocker::status_one_recv.arg(bp).arg(lp).arg(WlLocker::OPEN);
    QString status = "";
    if (!recv.isEmpty()) {
        QString recv_cmd = serial.bytes2Hex(recv.mid(3, 1));
        qDebug() << recv_cmd;
        if (recv_cmd == QString("06")) {
            QString state = serial.bytes2Hex(recv.mid(6, 1));
            qDebug() << state;
            if (state == WlLocker::OPEN) {
                status = QObject::tr("开启");
            } else {
                status = QObject::tr("关闭");
            }
        } else {
            status = QObject::tr("开锁失败");
        }

    } else {
        status = QObject::tr("接收错误");
    }

    insertData(SqliteUtil::TABLE_NAME, board_pos.toInt(), lock_pos.toInt(), status);
    ui->lock_status_btn->setEnabled(true);
}

/**
 * @brief Widget::on_open_one_btn_clicked
 * 开启锁
 */
void Widget::on_open_one_btn_clicked()
{
    emit delTable();
    QString board_pos = ui->board_pos->text();
    QString lock_pos = ui->lock_pos->text();
    if (board_pos.isEmpty()) {
        QMessageBox::about(NULL, QObject::tr("提示"), QObject::tr("请输入板号！"));
        return;
    }
    if (lock_pos.isEmpty()) {
        QMessageBox::about(NULL, QObject::tr("提示"), QObject::tr("请输入锁号！"));
        return;
    }

    ui->open_one_btn->setEnabled(false);
    // 转换输入的板号和锁号为16进制
    QString bp = QString("%1").arg(board_pos.toInt(), 2, 16, QLatin1Char('0'));
    QString lp = QString("%1").arg(lock_pos.toInt(), 2, 16, QLatin1Char('0'));
    // 拼接发送命令
    QString send_cmd = WlLocker::open_one_send.arg(bp).arg(lp);
    // 计算命令的crc值
    QString crc = crcSum16(send_cmd);
    send_cmd = send_cmd + crc;

    ui->send_cmd->setText(send_cmd);
    QByteArray recv = serial.sendAndRead(send_cmd);
    qDebug() << recv;
    QString status = "";
    if (!recv.isEmpty()) {
        QString recv_cmd = serial.bytes2Hex(recv.mid(3, 1));
        if (recv_cmd == QString("06")) {
            QString state = serial.bytes2Hex(recv.mid(6, 1));
            qDebug() << state;
            if (state == WlLocker::OPEN) {
                status = QObject::tr("开启");
            } else {
                status = QObject::tr("关闭");
            }
        } else {
            status = QObject::tr("开锁失败");
        }
    } else {
        status = QObject::tr("接收错误");
    }
    insertData(SqliteUtil::TABLE_NAME, board_pos.toInt(), lock_pos.toInt(), status);
    ui->open_one_btn->setEnabled(true);
}

/**
 * @brief Widget::on_all_status_btn_clicked
 * 获取所有锁状态
 */
void Widget::on_all_status_btn_clicked()
{
    emit delTable();
    QString board_num = ui->board_num->text();
    QString lock_num = ui->lock_num->text();
    if (board_num.isEmpty()) {
        QMessageBox::about(NULL, QObject::tr("提示"), QObject::tr("请输入板数！"));
        return;
    }
    if (lock_num.isEmpty()) {
        QMessageBox::about(NULL, QObject::tr("提示"), QObject::tr("请输入锁数！"));
        return;
    }

    ui->all_status_btn->setEnabled(false);
    for (int i=1; i<=board_num.toInt(); i++) {
        for (int j=1; j<=lock_num.toInt(); j++) {
            QString send_cmd = WlLocker::status_one_send;
            // 转换输入的板号和锁号为16进制
            QString bp = QString("%1").arg(i, 2, 16, QLatin1Char('0'));
            QString lp = QString("%1").arg(j, 2, 16, QLatin1Char('0'));
            send_cmd = send_cmd.arg(bp).arg(lp);
            qDebug() << send_cmd;
            // 计算命令的crc值
            QString crc = crcSum16(send_cmd);
            qDebug() << crc;
            send_cmd = send_cmd + crc;
            qDebug() << send_cmd;

            ui->send_cmd->setText(send_cmd);
            QByteArray recv = serial.sendAndRead(send_cmd);
            QString status = "";
            if (!recv.isEmpty()) {
                QString recv_cmd = serial.bytes2Hex(recv.mid(3, 1));
                if (recv_cmd == QString("06")) {
                    QString state = serial.bytes2Hex(recv.mid(6, 1));
                    if (state == WlLocker::OPEN) {
                        status = QObject::tr("开启");
                    } else {
                        status = QObject::tr("关闭");
                    }
                } else {
                    status = QObject::tr("开锁失败");
                }

            } else {
                status = QObject::tr("接收错误");
            }

            insertData(SqliteUtil::TABLE_NAME, i, j, status);
            // 暂停1秒
            Common::sleep(1000);
        }
    }
    ui->all_status_btn->setEnabled(true);
}

/**
 * @brief Widget::on_open_all_btn_clicked
 * 开启所有锁
 */
void Widget::on_open_all_btn_clicked()
{
    emit delTable();
    QString board_num = ui->board_num->text();
    QString lock_num = ui->lock_num->text();
    if (board_num.isEmpty()) {
        QMessageBox::about(NULL, QObject::tr("提示"), QObject::tr("请输入板数！"));
        return;
    }
    if (lock_num.isEmpty()) {
        QMessageBox::about(NULL, QObject::tr("提示"), QObject::tr("请输入锁数！"));
        return;
    }

    ui->open_all_btn->setEnabled(false);
    for (int i=1; i<=board_num.toInt(); i++) {
        for (int j=1; j<=lock_num.toInt(); j++) {
            QString send_cmd = WlLocker::open_one_send;
            // 转换输入的板号和锁号为16进制
            QString bp = QString("%1").arg(i, 2, 16, QLatin1Char('0'));
            QString lp = QString("%1").arg(j, 2, 16, QLatin1Char('0'));
            send_cmd = send_cmd.arg(bp).arg(lp);
            qDebug() << send_cmd;
            // 计算命令的crc值
            QString crc = crcSum16(send_cmd);
            send_cmd = send_cmd + crc;

            ui->send_cmd->setText(send_cmd);
            QByteArray recv = serial.sendAndRead(send_cmd);
            QString status = "";
            if (!recv.isEmpty()) {
                QString recv_cmd = serial.bytes2Hex(recv.mid(3, 1));
                qDebug() << recv_cmd;
                if (recv_cmd == QString("06")) {
                    QString state = serial.bytes2Hex(recv.mid(6, 1));
                    qDebug() << state;
                    if (state == WlLocker::OPEN) {
                        status = QObject::tr("开启");
                    } else {
                        status = QObject::tr("关闭");
                    }
                } else {
                    status = QObject::tr("开锁失败");
                }

            } else {
                status = QObject::tr("接收错误");
            }

            insertData(SqliteUtil::TABLE_NAME, i, j, status);
            // 暂停1秒
            Common::sleep(1000);
        }
    }
    ui->open_all_btn->setEnabled(true);
}
